package com.appredes.controller;

import com.appredes.model.InternetProtocol;
import com.appredes.model.Ranges;
import com.appredes.model.SubNeting;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.JOptionPane; 
import javax.swing.JTextArea;

/***
 * @author David Cuellar
 * @version 1.0
 * @created 22-oct-2011 06:39:28 p.m.
 */
public class Controller {
    
    private InternetProtocol ip;
    private Ranges ranges;
    private String tipoClase;
    private SubNeting subneting;
    
    public Controller(){
        
        ip = new InternetProtocol();
        ranges = new Ranges();
        subneting = new SubNeting();
    }

    public boolean crearIP(String IP){
        
        StringTokenizer tk = new StringTokenizer(IP,".",false);
        
        try{
            
            if(tk.countTokens() == 4){
                ip.setOcteto1(Short.parseShort(tk.nextToken()));
                ip.setOcteto2(Short.parseShort(tk.nextToken()));
                ip.setOcteto3(Short.parseShort(tk.nextToken()));
                ip.setOcteto4(Short.parseShort(tk.nextToken()));
                
                return true;
                
                
            }
            else{
                 JOptionPane.showMessageDialog(null, "IP No Valida.\n\n Debe tener 4 Octetos", "Error de IP", JOptionPane.ERROR_MESSAGE);
                 return false;
            }
        }
        catch(Exception ex){
            
            if(ex.toString().contains("java.lang.NumberFormatException: Value out of range"))
                JOptionPane.showMessageDialog(null, "IP No Valida.\n\n El rango de cada octeto debe estar entre 0 y 255", "Error de rango", JOptionPane.ERROR_MESSAGE);
            if(ex.toString().contains("java.lang.NumberFormatException: For input string"))
                JOptionPane.showMessageDialog(null, "IP No Valida.\n\n No puede contener Caracteres", "Error de Caracteres", JOptionPane.ERROR_MESSAGE);
            
            return false;
        }
        
    }
    
    public String getTipoClase(){
        
        return ip.getClassType();
    }
    
    public String getRangoClases(){
        
        return ip.getRangeOfAddress();
    }
    
    public int getNumeroOfRedes(){
        
        return ip.getNumberOfNets();
    }
    
    public int getNumeroOfHosts(){
        
        return ip.getNumberOfHosts();
    }
    
    public String getMascaraPredeterminada(){
        
        return ip.getMask();
    }
    
    /**
     * SUBNETING
     */
    
    
    public void calcularBitRobar(short pNumberOfNets){
        
        subneting.calculateBitToSteel(pNumberOfNets);
        
    }
    
    public  ArrayList<String> calcularMascara(short Redes){
        
        System.out.println("Octeto 1 = "+ip.getOcteto1());
        
        ArrayList<String> txaArea = new ArrayList<String>();
        short rango = 0;
        short i = 0;
        double expo = 0;
        int totalHost = 0;
        String newMask = "";
        
        short saltos = (short)(256 - subneting.getRangeOfSubnets());
        
        /* Si es A*/
        if(ip.getOcteto1() <= 127){
             
            if(Redes <= 128){
                
                expo = (short)(24 - subneting.getBitsToSteel());
                totalHost = (int)Math.pow(2.0, expo)-2;

                while(rango < 255){   
                    txaArea.add("Red "+(i+1)+" : "+"Desde : "+ip.getOcteto1()+"."+rango+"."+"0.0  "
                                                  + "Hasta : "+ip.getOcteto1()+"."+(rango+saltos-1)+"."+"255.255\n");

                    rango = (short)(rango + saltos);
                    i++;

                }           
                txaArea.add("\nHost asignables por red : "+totalHost+"\n"); 
                txaArea.add("Nueva Mascara : 255."+subneting.getValueOfMask()+".0.0");

                return txaArea;
            }
            else{
                JOptionPane.showMessageDialog(null, "El numero de redes no es valido para este tipo de IP", "Error", JOptionPane.ERROR_MESSAGE);
                return null;
            }
        }
        /* Si es B*/
        if(ip.getOcteto1() >= 128 && ip.getOcteto1() <= 191){
             
            if(Redes <= 16384){
                expo = (short)(16 - subneting.getBitsToSteel());
                totalHost = (int)Math.pow(2.0, expo)-2;

                while(rango < 255){   
                    txaArea.add("Red "+(i+1)+" : "+"Desde : "+ip.getOcteto1()+"."+ip.getOcteto2()+"."+rango+"."+"0  "
                                                  + "Hasta : "+ip.getOcteto1()+"."+ip.getOcteto2()+"."+(rango+saltos-1)+"."+"255\n");

                    rango = (short)(rango + saltos);
                    i++;

                }           
                txaArea.add("\nHost asignables por red : "+totalHost+"\n");
                txaArea.add("Nueva Mascara : 255.255."+subneting.getValueOfMask()+".0");
                return txaArea;
            }
            else{
                JOptionPane.showMessageDialog(null, "El numero de redes no es valido para este tipo de IP", "Error", JOptionPane.ERROR_MESSAGE);
                return null;
            }
                
        }
        /* Si es C*/
        if(ip.getOcteto1() >= 192 && ip.getOcteto1() <= 223){
             
            if(Redes <= 2097152){
                expo = (short)(8 - subneting.getBitsToSteel());
                totalHost = (int)Math.pow(2.0, expo)-2;

                while(rango < 255){   
                    txaArea.add("Red "+(i+1)+" : "+"Desde : "+ip.getOcteto1()+"."+ip.getOcteto2()+"."+ip.getOcteto3()+"."+rango
                                                  + "  Hasta : "+ip.getOcteto1()+"."+ip.getOcteto2()+"."+ip.getOcteto3()+"."+(rango+saltos-1)+"\n");

                    rango = (short)(rango + saltos);
                    i++;

                }           
                txaArea.add("\nHost asignables por red : "+totalHost+"\n");
                txaArea.add("Nueva Mascara : 255.255.255."+subneting.getValueOfMask());
                return txaArea;
            }
            else{
                JOptionPane.showMessageDialog(null, "El numero de redes no es valido para este tipo de IP", "Error", JOptionPane.ERROR_MESSAGE);
                return null;
            }
        }
        
        return null;

    }
    
}
